<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>防抖</title>
	<style type="text/css" media="screen">
		#content{
			height:150px;
			line-height:150px;
			text-align:center; color: 
			#fff;background-color:#ccc;
			font-size:80px;
		}
	</style>
</head>
<body>
	<div id="content"></div>
	<script type="text/javascript">
		// 适用场景： input
		let num = 1;
	  	let content = document.getElementById('content');
	  	// 页面内容 + 1
		function count() {
	        content.innerHTML = num++;
	    }
		// 1、 防抖 ------ 非立即执行
		function debounce(fn, wait){
			let timer;
			return function(){
				const context = this;
				const args = arguments;
				if(timer) clearTimeout(timer)
				timer = setTimeout(() => {
					fn.apply(context, args)
				}, wait)
			}
		}
		// 2、 防抖 ------ 立即执行
		function debounce1(fn, wait){
			let timer;
			return function(){
				const context = this;
				const args = arguments;
				if(timer) clearTimeout(timer);
				const immediately = !timer;
				// 这里 timer 的值在执行完setTimeout时，为一个常量numner,在下一个事件循环的回调中才会被赋值为null，所以，当再次触发函数时，！timer的值为false,是不会触发函数的，只有当等待时间过去之后，当前执行栈中没有任务执行时，才会触发回调队列中的 timer = null 的回调函数
				timer = setTimeout(() => {
					timer = null
				}, wait)
				if(immediately) fn.apply(context, args)
			}
		}
		// 3、 防抖 ------ 立即执行/延迟执行结合
		function debounce2(fn, wait, immediately){
			let timer;
			return function(){
				const context = this;
				const args = arguments;
				if(timer) clearTimeout(timer)
				if(immediately){
					const canNow = !timer;
					timer = setTimeout(() => {
						timer = null
					}, wait)
					if(canNow) fn.apply(context, args)
				} else{
					timer = setTimeout(() => {
						fn.apply(context, args)
					}, wait)
				}
			}
		}
		// 鼠标划过时，触发函数+1函数
		content.onmousemove = debounce(count, 1500)
	</script>
</body>
</html>